<?php

namespace addons\csmitsm\library\xcore\xcore\utils;

use addons\csmitsm\library\sdnode\xstack\utils\XsDatetimeUtils;
use Exception;
use think\Loader;
use Cron\CronExpression;
use addons\csmitsm\library\xcore\xcore\utils\XcIncludeFileUtils;
use addons\csmitsm\library\xcore\xcore\XcException;

class XcCrontaskUtils
{
    private static function init()
    {
        if (!class_exists('\Cron\CronExpression')) {
            $path = XcIncludeFileUtils::getAddonsPath("/library/xcore/xcore/utils/lib/Cron");
            Loader::addNamespace('Cron',  $path);
        }
    }
    public static function assertValidCronexpression($cronexpression)
    {
        static::init();
        try {
            return CronExpression::factory($cronexpression);
        } catch (Exception $e) {
            throw new XcException("{$cronexpression}格式不合法");
        }
    }

    /**
     * nextimes = XcCrontaskUtils::nexttime($cronexpression, 3);
     * @return array
     */
    public static function nexttimes($cronexpression, $count)
    {
        $cron = static::assertValidCronexpression($cronexpression);

        // 获取多次执行时间
        $currentDate = new \DateTime();
        $nextRunDates = [];

        for ($i = 0; $i < 3; $i++) {
            $currentDate = $cron->getNextRunDate($currentDate);
            $nextRunDates[] = XsDatetimeUtils::datetimeToTimestamp($currentDate);
            // $nextRunDates[] = $nextRunDate->format('Y-m-d H:i:s');
        }
        return $nextRunDates;
    }

    /**
     * 
     * 
     * @param mixed $cronexpression
     * @return bool
     */
    public static function canExecute($cronexpression)
    {
        $cron = static::assertValidCronexpression($cronexpression);
        return $cron->isDue();
    }

    /**
     * 
     * [$result, $loggerMessage] = XcCrontaskUtils::execute("addons\csmitsm\crontask\XpTest", "mm");
     * @return array
     */
    public static function execute($taskcls, $taskmethod)
    {
        [$result, $loggerMessage] = [null, null];
        try {
            [$result, $loggerMessage] = XcTransactionUtils::service(function () use ($taskcls, $taskmethod) {
                $taskInstance = XcReflectionClassUtils::newInstance($taskcls);
                $result = $taskInstance->$taskmethod();
                $loggerMessage = $taskInstance->getLoggerMessage();
                return [$result, $loggerMessage];
            });
        } catch (Exception $e) {
            [$result, $loggerMessage] = [false, $e->getMessage()];
        }
        return [$result, $loggerMessage];
    }
}
